package com.rainbow.modules.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rainbow.common.util.ResultUtil;
import com.rainbow.common.vo.PageVo;
import com.rainbow.common.vo.Result;
import com.rainbow.modules.sys.entity.Role;
import com.rainbow.modules.sys.entity.RoleDepartment;
import com.rainbow.modules.sys.entity.RolePermission;
import com.rainbow.modules.sys.entity.UserRole;
import com.rainbow.modules.sys.service.RoleDepartmentService;
import com.rainbow.modules.sys.service.RolePermissionService;
import com.rainbow.modules.sys.service.RoleService;
import com.rainbow.modules.sys.service.UserRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

/**
 * Auth rainbow
 */
@Slf4j
@RestController
@Api(description = "角色管理接口")
@RequestMapping("/rainbow/role")
@Transactional
public class RoleController {
    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private RoleDepartmentService roleDepartmentService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping(value = "/getAllList")
    @ApiOperation(value = "获取全部角色")
    public Result<Object> roleGetAll() {

        List<Role> list = roleService.list();
        return new ResultUtil<Object>().setData(list);
    }

    @GetMapping(value = "/getAllByPage")
    @ApiOperation(value = "分页获取角色")
    public Result<IPage<Role>> getRoleByPage(@ModelAttribute PageVo pageVo) {

        IPage<Role> page = roleService.page(new Page<>(pageVo.getPageNumber(), pageVo.getPageSize()));
        for (Role role : page.getRecords()) {
            // 角色拥有权限
            List<RolePermission> permissions = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id", role.getId()));
            role.setPermissions(permissions);
            // 角色拥有数据权限
            List<RoleDepartment> departments = roleDepartmentService.list(new QueryWrapper<RoleDepartment>().eq("role_id", role.getId()));
            role.setDepartments(departments);
        }
        return new ResultUtil<IPage<Role>>().setData(page);
    }

    @PostMapping(value = "/setDefault")
    @ApiOperation(value = "设置或取消默认角色")
    public Result<Object> setDefault(@RequestParam String id,
                                     @RequestParam Boolean isDefault) {

        Role role = roleService.getById(id);
        if (role == null) {
            return new ResultUtil<Object>().setErrorMsg("角色不存在");
        }
        role.setDefaultRole(isDefault);
        roleService.updateById(role);
        return new ResultUtil<Object>().setSuccessMsg("设置成功");
    }

    @PostMapping(value = "/editRolePerm")
    @ApiOperation(value = "编辑角色分配菜单权限")
    public Result<Object> editRolePerm(@RequestParam String roleId,
                                       @RequestParam(required = false) String[] permIds) {

        //删除其关联权限
        rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));
        //分配新权限
        for (String permId : permIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permId);
            rolePermissionService.save(rolePermission);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return new ResultUtil<Object>().setData(null);
    }

    @PostMapping(value = "/editRoleDep")
    @ApiOperation(value = "编辑角色分配数据权限")
    public Result<Object> editRoleDep(@RequestParam String roleId,
                                      @RequestParam Integer dataType,
                                      @RequestParam(required = false) String[] depIds) {

        Role r = roleService.getById(roleId);
        r.setDataType(dataType);
        roleService.updateById(r);
        // 删除其关联数据权限
        roleDepartmentService.remove(new QueryWrapper<RoleDepartment>().eq("role_id", roleId));
        // 分配新数据权限
        for (String depId : depIds) {
            RoleDepartment roleDepartment = new RoleDepartment();
            roleDepartment.setRoleId(roleId);
            roleDepartment.setDepartmentId(depId);
            roleDepartmentService.save(roleDepartment);
        }
        // 手动删除相关缓存
        Set<String> keys = redisTemplate.keys("department:" + "*");
        redisTemplate.delete(keys);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);

        return new ResultUtil<Object>().setData(null);
    }

    @PostMapping(value = "/save")
    @ApiOperation(value = "保存数据")
    public Result<Role> save(@ModelAttribute Role role) {

        boolean r = roleService.save(role);
        return new ResultUtil<Role>().setData(roleService.getById(role.getId()));
    }

    @PostMapping(value = "/edit")
    @ApiOperation(value = "更新数据")
    public Result<Role> edit(@ModelAttribute Role entity) {

        boolean r = roleService.updateById(entity);
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        return new ResultUtil<Role>().setData(entity);
    }

    @DeleteMapping(value = "/delAllByIds/{ids}")
    @ApiOperation(value = "批量通过ids删除")
    public Result<Object> delByIds(@PathVariable String[] ids) {

        for (String id : ids) {
            List<UserRole> list = userRoleService.list(new QueryWrapper<UserRole>().eq("role_id", id));
            if (list != null && list.size() > 0) {
                return new ResultUtil<Object>().setErrorMsg("删除失败，包含正被用户使用关联的角色");
            }
        }
        for (String id : ids) {
            roleService.removeById(id);
            //删除关联菜单权限
            rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", id));
            //删除关联数据权限
            roleDepartmentService.remove(new QueryWrapper<RoleDepartment>().eq("role_id", id));
        }
        return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
    }

}
